// Copyright Notice:
//			     colortool_calc.js v1.0.1
//			Copyright@2008 - OpenSiteMobile
//				All rights reserved
// ==========================================================================
//			http://www.opensitemobile.com
// ==========================================================================
// Contact Information:
//			Author: Dwight Vietzke
//			Email:  dwight_vietzke@yahoo.com

/*
	OpenSiteMobile colortool base functions w/dojo integration
*/

dojo.provide("msos.colortool_calc");
dojo.require("msos.common");
dojo.require("msos.tab");
dojo.require("msos.number_ctrl");
dojo.require("msos.validate");
dojo.require("dojo.cookie");
dojo.require("dojo.i18n");


msos.colortool_calc.generate_colortool = function(ct_elms) {
    this.select_method = 'Rgb';
    this.saved_color_elm = null;
    this.web_safe_elm = null;
    this.numeric_controls = [];
    this.pointer_offset = 3;	// Compensate for image placement relative to center

    // RGB color arrays
    this.saved_rgb_colors = new Array();
    this.current_rgb_color = new Array();

    // Provide a bundled object
    var ct_obj = this;

    // Get the language file to use as base
    dojo.requireLocalization('msos', 'colortool', djConfig.locale);
    var i18n_ct = dojo.i18n.getLocalization('msos', 'colortool', djConfig.locale);

    // Set some language specific text
    ct_elms.ct_wheel_img.alt	= i18n_ct.ct_wheel_img;
    ct_elms.rgb_r.title		= i18n_ct.rgb_r + ' (0 - 255)';
    ct_elms.hsb_h.title		= i18n_ct.hsb_h + ' (0 - 360)';
    ct_elms.rgb_g.title		= i18n_ct.rgb_g + ' (0 - 255)';
    ct_elms.hsb_s.title		= i18n_ct.hsb_s + ' (0 - 100)';
    ct_elms.rgb_b.title		= i18n_ct.rgb_b + ' (0 - 255)';
    ct_elms.hsb_v.title		= i18n_ct.hsb_v + ' (0 - 100)';
    ct_elms.ct_web_smart.title	= i18n_ct.ct_web_smart;
    ct_elms.ct_update_main.value= i18n_ct.ct_update_main_value;
    ct_elms.ct_update_main.title= i18n_ct.ct_update_main_title;
    ct_elms.ct_hex_inp.title	= i18n_ct.ct_hex_inp;
    ct_elms.ct_save_color.value	= i18n_ct.ct_save_color_value;
    ct_elms.ct_save_color.title	= i18n_ct.ct_save_color_title;
    ct_elms.ct_save_color.value	= i18n_ct.ct_save_color_value;
    ct_elms.ct_save_color.title	= i18n_ct.ct_save_color_title;
    ct_elms.ct_use_color.value	= i18n_ct.ct_use_color_value;
    ct_elms.ct_use_color.title	= i18n_ct.ct_use_color_title;

    // Don't allow overflow (Opera, Chrome)
    // Note: When numeric controls get added, they cause shift in main tab which
    //       screws up their position.
    ct_elms.ct_main_tab.style.overflow = 'hidden';
    
    this.run_input_update = function() {
	if	(ct_obj.select_method == 'Rgb') { ct_obj.rgb_form_set_color(); }
	else if	(ct_obj.select_method == 'Hsb') { ct_obj.hsb_form_set_color(); }
	else if	(ct_obj.select_method == 'Hex') { ct_obj.hex_form_set_color(); }
	console.debug('run_input_update -> method: ' + ct_obj.select_method);
    }

    this.set_hex_input = function(hex_color) {
	var text;
	hex_color = hex_color.toUpperCase();
	if (toggle_dark_light(hex_color))	{ text = 'white'; }
	else					{ text = 'black'; }
	ct_elms.ct_hex_inp.style.backgroundColor = '#' + hex_color;
	ct_elms.ct_hex_inp.style.color = text;
	ct_elms.ct_hex_inp.value = '#' + hex_color;
    }

    this.set_display = function(dis_color) {
	var text;
	dis_color = dis_color.toUpperCase();
	if (toggle_dark_light(dis_color))	{ text = 'white'; }
	else					{ text = 'black'; }
	ct_elms.ct_display.style.backgroundColor = '#' + dis_color;
	ct_elms.ct_display.style.color = text;
	ct_elms.ct_display.innerHTML =	 '#' + dis_color;
    }

    this.clear_saved_colors = function() {
	ct_obj.saved_rgb_colors = new Array();
	dojo.cookie('ct_saved_color', null, { expires:-1 });
	ct_obj.display_saved_colors();
    }

    this.clear_pointer = function() {
	ct_elms.black_circle.style.display = 'none';
	ct_elms.white_circle.style.display = 'none';
    }

    this.safe_tab_reset = function() {
	if (ct_obj.web_safe_elm) {
	    ct_obj.web_safe_elm.style.border = '1px inset';
	    ct_obj.web_safe_elm.style.cursor = 'crosshair';
	}
    }

    this.set_pointer = function() {
	var color = rgb_to_hex(ct_obj.current_rgb_color);
	var coord = ct_obj.get_pointer_coordinates();

	if(toggle_dark_light(color)) {
	    ct_elms.white_circle.style.left = coord.x + 'px';
	    ct_elms.white_circle.style.top  = coord.y + 'px';
	    ct_elms.black_circle.style.display = 'none';
	    ct_elms.white_circle.style.display = 'inline';
	} else {
            ct_elms.black_circle.style.left = coord.x + 'px';
	    ct_elms.black_circle.style.top  = coord.y + 'px';
	    ct_elms.black_circle.style.display = 'inline';
	    ct_elms.white_circle.style.display = 'none';
	  }
	console.debug('set_pointer -> left:' + coord.x + ', top:' + coord.y);
    }

    this.update_input_form = function (rgb, hsb) {
	console.info('update_input_form -> Called!');
	ct_obj.clear_pointer();

	ct_elms.rgb_r.value = rgb[0];
	ct_elms.rgb_g.value = rgb[1];
	ct_elms.rgb_b.value = rgb[2];
	ct_elms.hsb_h.value = hsb[0];
	ct_elms.hsb_s.value = hsb[1];
	ct_elms.hsb_v.value = hsb[2];

	var hex_color = rgb_to_hex(rgb);

	ct_obj.set_hex_input(hex_color);
	  ct_obj.set_display(hex_color);

	ct_obj.current_rgb_color = rgb;
	ct_obj.set_pointer();
    }

    this.rgb_form_set_color = function() {
	ct_obj.rgb_set_color(ct_elms.rgb_r.value, ct_elms.rgb_g.value, ct_elms.rgb_b.value);
    }

    this.hsb_form_set_color = function() {
	ct_obj.hsb_set_color(ct_elms.hsb_h.value, ct_elms.hsb_s.value, ct_elms.hsb_v.value);
    }

    this.hex_form_set_color = function() {
	var check_color = msos.validate.check_hex_color(ct_elms.ct_hex_inp.value)
	if (!check_color) {
	    if (msos.common.var_is_null(check_color)) {
		ct_obj.set_hex_input(rgb_to_hex(ct_obj.current_rgb_color));
	    } else {
		alert(check_color + ' - ???');
	      }
	    ct_elms.ct_hex_inp.focus();
	    return false;
	}
	ct_obj.hex_set_color(check_color);
	return true;
    }

    this.hsb_set_color = function(h, s, v) {
	var rgb = hsv2rgb(h, s/100, v/100);
	ct_obj.update_input_form(rgb, new Array(h, s, v));
	console.debug('hsb_set_color -> called update_input_form!');
    }

    this.rgb_set_color = function(r, g, b) {
	var hsb = rgb2hsv(r, g, b);
	ct_obj.update_input_form(new Array(r, g, b), new Array(parseInt(hsb.hue), parseInt(hsb.sat * 100), parseInt(hsb.val * 100)));
	console.debug('rgb_set_color -> called update_input_form!');
    }

    this.hex_set_color = function(hex) {
	var r = msos.common.hex_to_dec(hex.substr(0,2));
	var g = msos.common.hex_to_dec(hex.substr(2,2));
	var b = msos.common.hex_to_dec(hex.substr(4,2));
	ct_obj.rgb_set_color(r, g, b);
	console.debug('hex_set_color -> called rgb_set_color!');
    }

    // --------------------------
    // Event functions
    // --------------------------

    this.update_safe_color = function(evt) {
	var tar = evt.target;
	if (ct_obj.web_safe_elm) {
	    ct_obj.web_safe_elm.style.border = '1px inset';
	    ct_obj.web_safe_elm.style.cursor = 'crosshair';
	}
	ct_obj.web_safe_elm = tar;
	tar.style.border = '1px outset';
	tar.style.cursor = 'default';
	ct_obj.hex_set_color(tar.update_color);
	msos.common.event_debug(evt, "\nUpdate safe color:\nhex -> " + tar.style.backgroundColor);
    }

    this.onclick_saved_colors = function(evt) {
	var tar = evt.target;
	if (ct_obj.saved_color_elm) {
	    ct_obj.saved_color_elm.style.border = '2px inset';
	    ct_obj.saved_color_elm.style.cursor = 'crosshair';
	}
	ct_obj.saved_color_elm = tar;
	tar.style.border = '2px outset';
	tar.style.cursor = 'default';
	ct_obj.rgb_set_color(tar.r, tar.g, tar.b);
	var temp_txt = "\nSaved color click:\nR -> " + tar.r + "\nG -> " + tar.g + "\nB -> " + tar.b;
	msos.common.event_debug(evt, temp_txt);
    }

    this.initiate_tabs = function() {
	// Generate our colortool tabs
	var tab_obj = new msos.tab.tool(ct_elms.ct_tabs_div);
	tab_obj.act_tab_style = 'tab_active';
	tab_obj.pas_tab_style = 'tab_passive';
	tab_obj.tab_cookie_name = 'colortool_tab';
	tab_obj.tab_height_px = 256;    // this is as small as we can go...

        var main_onclick = function() { tab_obj.go_to_tab(); }

        // Get the tab index if saved to a cookie
	tab_obj.get_tab_by_cookie();

	var main_tab = {
	    caption :		i18n_ct['ct_txt_6'],
	    tab_title :		i18n_ct['ct_txt_7'],
	    container :		ct_elms.ct_main_tab
	}
	var safe_tab = {
	    caption :		i18n_ct['ct_txt_8'],
	    tab_title :		i18n_ct['ct_txt_9'],
	    container :		ct_elms.ct_websafe_tab
	}
	var save_tab = {
	    caption :		i18n_ct['ct_txt_10'],
	    tab_title :		i18n_ct['ct_txt_11'],
	    container :		ct_elms.ct_saved_tab
	}
	tab_obj.add_tab(main_tab);
	tab_obj.add_tab(safe_tab);
	tab_obj.add_tab(save_tab);

	tab_obj.generate_tabs();

        // Add specific colortool functions for when a tab is clicked
        tab_obj.tab_onclick = function() {
            if          (tab_obj.tab_set_active == 1) {
                for (var num in ct_obj.numeric_controls) {
                    ct_obj.numeric_controls[num].container_position();
                }
            } else if   (tab_obj.tab_set_active == 2) {
                ct_obj.safe_tab_reset();
              }
        }
	console.debug('initiate_tabs -> finished');
    }

    this.initiate_num_ctrls = function() {

	// Generate our numeric input controls
	var num1,num2,num3,num4,num5,num6;
	num1 = new msos.number_ctrl.tool(ct_elms.rgb_r);
	num1.num_min_val = 0;
	num1.num_max_val = 255;
	num1.num_ctrl_left = -6;
	num1.num_ctrl_top = -2;
	num1.num_ctrl_id = 'rgb - red';
	num1.after_change_function = ct_obj.rgb_form_set_color;
	num1.generate_num_ctrl();

	num2 = new msos.number_ctrl.tool(ct_elms.rgb_g);
	num2.num_min_val = 0;
	num2.num_max_val = 255;
	num2.num_ctrl_left = -6;
	num2.num_ctrl_top = -2;
	num2.num_ctrl_id = 'rgb - green';
	num2.after_change_function = ct_obj.rgb_form_set_color;
	num2.generate_num_ctrl();

	num3 = new msos.number_ctrl.tool(ct_elms.rgb_b);
	num3.num_min_val = 0;
	num3.num_max_val = 255;
	num3.num_ctrl_left = -6;
	num3.num_ctrl_top = -2;
	num3.num_ctrl_id = 'rgb - blue';
	num3.after_change_function = ct_obj.rgb_form_set_color;
	num3.generate_num_ctrl();

	num4 = new msos.number_ctrl.tool(ct_elms.hsb_h);
	num4.num_min_val = 0;
	num4.num_max_val = 360;
	num4.num_ctrl_left = -6;
	num4.num_ctrl_top = -2;
	num4.num_ctrl_id = 'hsb - hue';
	num4.after_change_function = ct_obj.hsb_form_set_color;
	num4.generate_num_ctrl();

	num5 = new msos.number_ctrl.tool(ct_elms.hsb_s);
	num5.num_min_val = 0;
	num5.num_max_val = 100;
	num5.num_ctrl_left = -6;
	num5.num_ctrl_top = -2;
	num5.num_ctrl_id = 'hsb - sat';
	num5.after_change_function = ct_obj.hsb_form_set_color;
	num5.generate_num_ctrl();

	num6 = new msos.number_ctrl.tool(ct_elms.hsb_v);
	num6.num_min_val = 0;
	num6.num_max_val = 100;
	num6.num_ctrl_left = -6;
	num6.num_ctrl_top = -2;
	num6.num_ctrl_id = 'hsb - bright';
	num6.after_change_function = ct_obj.hsb_form_set_color;
	num6.generate_num_ctrl();

        ct_obj.numeric_controls = [
            num1.num_container, num2.num_container, num3.num_container,
            num4.num_container, num5.num_container, num6.num_container
        ];
    }

    this.generate_web_safe = function() {
	var c = new Array('00','CC','33','66','99','FF');
	var images_array = new Array();

	// Generate our image elements
	for (var i = 0; i < 6; i++) {
	    for (var j = 0; j < 6; j++) {
		for (var k = 0; k < 6; k++) {

		    // Generate hex color
		    var l = c[i] + c[j] + c[k];

		    // Create image for each color
		    var color_image = new Image();
		    color_image.src = djConfig.msos_folder + '/images/shim.gif';
		    color_image.className = 'ws_img';
		    color_image.style.backgroundColor = '#' + l;
		    color_image.unselectable = "on";
		    color_image.alt = 'hex ' + l;
		    color_image.title = '#' + l;
		    color_image.update_color = l.toString();
		    dojo.connect(color_image, 'onclick', null, ct_obj.update_safe_color);

		    images_array.push(color_image);
		}
	    }
	}

	// Now set them in our display div's
	for (var m = 0; m < 18; m++) {
	    var new_div = document.createElement("div");
	    new_div.classname = 'ws_row';
	    var new_array = images_array.splice(0, 12);
	    for (var n = 0; n < new_array.length; n++) {
	        new_div.appendChild(new_array[n]);
		if (n == 5) new_div.appendChild(document.createTextNode(' '));
	    }
	    ct_elms.ct_websafe_tab.appendChild(new_div);
	}
	console.debug('generate_web_safe -> finished');
    }

    this.display_saved_colors = function() {
	if (ct_obj.saved_rgb_colors.length == 0) {
	    ct_elms.ct_saved_tab.innerHTML = i18n_ct['ct_txt_1'] + '<br />';
	} else {
	    ct_elms.ct_saved_tab.innerHTML = i18n_ct['ct_txt_2'] + '<br />';
	    var scd = [];
	    for (var i=0; i<ct_obj.saved_rgb_colors.length; i++) {
		var clr = rgb_to_hex(ct_obj.saved_rgb_colors[i]);
		clr = clr.toUpperCase();

		scd[i] = document.createElement("div");
		scd[i].r = ct_obj.saved_rgb_colors[i][0];
		scd[i].g = ct_obj.saved_rgb_colors[i][1];
		scd[i].b = ct_obj.saved_rgb_colors[i][2];
		scd[i].className = 'ct_saved_colors';
		scd[i].title = '#' + clr;
		scd[i].style.backgroundColor = '#' + clr;
		scd[i].unselectable = "on";
		if (toggle_dark_light(clr)) { scd[i].style.color = 'white'; }

		dojo.connect(scd[i], 'onclick', null, ct_obj.onclick_saved_colors);
		scd[i].innerHTML = i18n_ct['ct_txt_3'] + ' '  + scd[i].r + ', ' + scd[i].g + ', ' + scd[i].b;
		ct_elms.ct_saved_tab.appendChild(scd[i]);
	    }
	    // Add a button to clear all entries
	    var clear_button = document.createElement("input");
	    clear_button.type = 'button';
	    clear_button.value = i18n_ct['ct_txt_4'];
	    clear_button.title = i18n_ct['ct_txt_5'];
	    clear_button.unselectable = "on";
	    dojo.connect(clear_button, 'onclick', null, ct_obj.clear_saved_colors);
	    ct_elms.ct_saved_tab.appendChild(clear_button);
	  }
    }

    this.save_to_cookie = function() {
	for (var i=0; i<ct_obj.saved_rgb_colors.length; i++) {
		if ((ct_obj.saved_rgb_colors[i][0] == ct_obj.current_rgb_color[0]) && (ct_obj.saved_rgb_colors[i][1] == ct_obj.current_rgb_color[1]) && (ct_obj.saved_rgb_colors[i][2] == ct_obj.current_rgb_color[2])) return;
	}
	ct_obj.saved_rgb_colors[ct_obj.saved_rgb_colors.length] = ct_obj.current_rgb_color;
	var clr_array = new Array;
	for (var i=0; i<ct_obj.saved_rgb_colors.length; i++) {
		clr_array[clr_array.length] = rgb_to_hex(ct_obj.saved_rgb_colors[i]);
	}
	dojo.cookie('ct_saved_color', dojo.toJson(clr_array), { expires:15 });
	ct_obj.display_saved_colors();
    }

    this.start_colortool = function() {

	// Store a computed hex value
	var calc_color = '000000';

	// Initiate the popup form fields (dialog data)
	var popup_obj = new msos.common.init_popup(window);

	if (!popup_obj.init_fields()) {
	    alert(i18n_ct.ct_failed);
	    return false;
	}

	// Get any saved colors 
	var colors_array = dojo.fromJson(dojo.cookie('ct_saved_color')) || [];

	for (var j = 0; j < colors_array.length; j++) {
	    ct_obj.saved_rgb_colors[ct_obj.saved_rgb_colors.length] = hex_to_rgb_array(colors_array[j]);
	}

	var colorwheel_move = function(evt) {
	    var pos = dojo.coords(evt.target);
	    // Get x,y coordinates from center of color wheel 
	    var x = (evt.pageX - pos.l) - 80;
	    var y = (evt.pageY - pos.t) - 80;
	    var color = calc_wheel_color(x, y);
	    if(ct_elms.ct_web_smart.checked)	calc_color = color.charAt(0) + color.charAt(0) + color.charAt(2) + color.charAt(2) + color.charAt(4) + color.charAt(4);
	    else				calc_color = color;
	    ct_obj.set_hex_input(calc_color);
	    return false;
	}

	var use_hover_color = function(evt) {
	    ct_obj.hex_set_color(calc_color);
	    return false;
	}

	var clear_hover_color = function() {
	    ct_obj.set_hex_input(rgb_to_hex(ct_obj.current_rgb_color));
	    return false;
	}

	dojo.connect(ct_elms.ct_wheel_img, "onclick",	 null, use_hover_color	);
	dojo.connect(ct_elms.ct_wheel_img, "onmouseout", null, clear_hover_color);
	dojo.connect(ct_elms.ct_wheel_img, "onmousemove",null, colorwheel_move	);

	var onfocus_hex_inp = function() { ct_obj.select_method = 'Hex'; }
	var onfocus_rgb_inp = function() { ct_obj.select_method = 'Rgb'; }
	var onfocus_hsb_inp = function() { ct_obj.select_method = 'Hsb'; }

	dojo.connect(ct_elms.ct_hex_inp,"onfocus", null, onfocus_hex_inp);
	dojo.connect(ct_elms.rgb_r,	"onfocus", null, onfocus_rgb_inp);
	dojo.connect(ct_elms.rgb_g,	"onfocus", null, onfocus_rgb_inp);
	dojo.connect(ct_elms.rgb_b,	"onfocus", null, onfocus_rgb_inp);
	dojo.connect(ct_elms.hsb_h,	"onfocus", null, onfocus_hsb_inp);
	dojo.connect(ct_elms.hsb_s,	"onfocus", null, onfocus_hsb_inp);
	dojo.connect(ct_elms.hsb_v,	"onfocus", null, onfocus_hsb_inp);

	  ct_elms.ct_buttons.style.display = 'inline';
	  ct_elms.ct_display.style.display = 'inline';
	ct_elms.ct_input_ref.style.display = 'inline';

	// Set initial color
	var checked_color = msos.validate.check_hex_color(ct_elms.ct_hex_inp.value);
	if (checked_color)	ct_obj.hex_set_color(checked_color);
	else			ct_obj.rgb_set_color(210, 26, 210);	// Some default value

	// Set ref. color div to the initial value as set above
	var initial_color = rgb_to_hex(ct_obj.current_rgb_color);
	ct_elms.ct_input_ref.style.backgroundColor = '#' + initial_color;
	ct_elms.ct_input_ref.title = i18n_ct['ct_txt_12'] + ': #' + initial_color;

	// Update main tab form
	dojo.connect(ct_elms.ct_update_main,"onclick", null, ct_obj.run_input_update);

	// Set ct_input_ref element to reset colortool to initial clr value
	dojo.connect(ct_elms.ct_input_ref,  "onclick", null, function() { ct_obj.hex_set_color(initial_color); });

	// Set the ct_use_color button to apply the current color value
	dojo.connect(ct_elms.ct_use_color,  "onclick", null, popup_obj.popup_action);

	// Set ct_save_color button to store the current clr for later ref.
	dojo.connect(ct_elms.ct_save_color, "onclick", null, ct_obj.save_to_cookie);

	// Generate the 'Web Safe' colors display
	ct_obj.generate_web_safe();

	// Initialize the saved tabs's output
	ct_obj.display_saved_colors();

        // Add numeric controls
        ct_obj.initiate_num_ctrls();

        // Initialize tabs
        ct_obj.initiate_tabs();
        
	console.debug('start_colortool -> finished');
	return true;
    }

    this.get_pointer_coordinates = function() {
	var radius = 0;
	var theta = 0;
	var coordinates = {
	    x:0,
	    y:0
	}
	var pos = dojo.coords(ct_elms.ct_wheel_img);
	var rgb_current = ct_obj.current_rgb_color;

	if	  ((rgb_current[0] ==   0) && (rgb_current[1] ==   0) && (rgb_current[2] ==   0)) {
	    coordinates.x = 0;
	    coordinates.y = 0;
	} else if ((rgb_current[0] == 255) && (rgb_current[1] == 255) && (rgb_current[2] == 255)) {
	    coordinates.x = -70;
	    coordinates.y = -70;
	} else {
	    var hsv = rgb2hsv(rgb_current[0], rgb_current[1], rgb_current[2]);
	    var radius_gt_eq = -1 * ((hsv.sat - 2) / 2);
	    var radius_lt    =  hsv.val / 2;
	    if (radius_lt == .5) radius = radius_gt_eq;
	    else		 radius = radius_lt;
	    console.debug('get_pointer_coordinates -> hue:' + hsv.hue + ', sat:' + hsv.sat + ', value:' + hsv.val + ', radius:' + radius);
	    coordinates = calculateCartesian(radius * 80, hsv.hue);
	}
	console.debug('get_pointer_coordinates -> x:' + coordinates.x + ', y:' + coordinates.y);

	coordinates.x += pos.l + 80 - ct_obj.pointer_offset;	
	coordinates.y += pos.t + 80 - ct_obj.pointer_offset;
	return coordinates;
    }
}


// --------------------------
// Helper Functions
// --------------------------

function calculatePolar(x, y){
    var qx = (x < 0)?0:1;
    var qy = (y < 0)?0:1;
    var q_idx = 2 * qy + qx;
    var quadrant = new Array(180,360,180,0);
    var polar = { r: 0, theta: 0 };
 	polar.r = Math.floor(Math.pow((Math.pow(x,2) + Math.pow(y,2)),0.5));
	polar.theta = quadrant[q_idx] + Math.floor(Math.atan(y/x)*360/2/Math.PI);
	return polar;
}

function calculateCartesian(r, theta){
    var cartesian = { x: 0, y: 0 };
 	cartesian.x = Math.floor(r * Math.cos(theta * 2 * Math.PI / 360));
 	cartesian.y = Math.floor(r * Math.sin(theta * 2 * Math.PI / 360));
	return cartesian;    
}

function calc_wheel_color(x, y) {
    var pol = calculatePolar(x, y);
    var sat = 0;
    var val = 0;
    var rgb = new Array(0, 0, 0);
    var hex_color = '';

    if (pol.r == 0) { return rgb; }
    else {
	var norm_r = pol.r / 80;
	if (norm_r > 1) {    // outside color wheel
	    rgb = new Array(255, 255, 255);
            sat = 1;
            val = 1;            
        } else if (norm_r >= .5) {
	    sat = 1 - ((norm_r - .5) * 2);
            val = 1;
	    rgb = hsv2rgb(pol.theta, sat, val);
	} else {
            sat = 1;
	    val = norm_r * 2;
	    rgb = hsv2rgb(pol.theta, sat, val);
	  }
    }
    hex_color = rgb_to_hex(rgb);
    return hex_color;
}

function hsv2rgb(Hdeg,S,V) {
    var R = 255;
    var G = 255;
    var B = 255;
    var H = Hdeg / 360;

    if (S == 0) {
	R *= V;
	G *= V;
	B *= V;
    } else {
	var var_h = H * 6;
	var var_i = Math.floor(var_h);
	var var_1 = V * (1 - S);
	var var_2 = V * (1 - S *      (var_h - var_i));
	var var_3 = V * (1 - S * (1 - (var_h - var_i)));

	if	(var_i == 0) { var_r = V ;    var_g = var_3; var_b = var_1 }
	else if (var_i == 1) { var_r = var_2; var_g = V;     var_b = var_1 }
	else if (var_i == 2) { var_r = var_1; var_g = V;     var_b = var_3 }
	else if (var_i == 3) { var_r = var_1; var_g = var_2; var_b = V	   }
	else if (var_i == 4) { var_r = var_3; var_g = var_1; var_b = V	   }
	else		     { var_r = V;     var_g = var_1; var_b = var_2 }

	R = var_r * 255;
	G = var_g * 255;
	B = var_b * 255;
    }
    return new Array(Math.round(R), Math.round(G), Math.round(B));
}

function rgb2hsv(red, green, blue) {
    red = red / 255;
    green = green / 255;
    blue = blue / 255;

    var myMax = Math.max(red, Math.max(green, blue));
    var myMin = Math.min(red, Math.min(green, blue));

    if (myMax > 0) { s = (myMax - myMin) / myMax; }
    else	   { s = 0;			  }

    if (s > 0) {
	var myDiff = myMax - myMin;
	var rc = (myMax - red) / myDiff;
	var gc = (myMax - green) / myDiff;
	var bc = (myMax - blue) / myDiff;
	if (red == myMax)	{ h = (bc - gc)     / 6; }
	if (green == myMax)	{ h = (2 + rc - bc) / 6; }
	if (blue == myMax)	{ h = (4 + gc - rc) / 6; }
    } else {
	h = 0;
      }
    if (h < 0) { h += 1; }
    return { 'hue': Math.round(h * 360), 'sat': s, 'val': myMax };
}

function toggle_dark_light(hexcolor) {
    var overall = 0;
    var digit1 = hexcolor.substr(0, 1);
    var digit2 = hexcolor.substr(2, 1);
    var digit3 = hexcolor.substr(4, 1);

    digit1 = msos.common.hex_eq_dec(digit1);
    digit2 = msos.common.hex_eq_dec(digit2);
    digit3 = msos.common.hex_eq_dec(digit3);

    digit1 = parseInt(digit1);
    digit2 = parseInt(digit2);
    digit3 = parseInt(digit3);

    overall = digit1 + digit2 + digit3;
    if (overall < 13) return true;
    return false;
}

function hex_to_rgb_array(hex_string) {
    if (typeof(hex_string) == 'undefined') return new Array(255, 255, 255);
    var r = msos.common.hex_to_dec(hex_string.substr(0,2));
    var g = msos.common.hex_to_dec(hex_string.substr(2,2));
    var b = msos.common.hex_to_dec(hex_string.substr(4,2));
    return new Array(r, g, b);
}

function rgb_to_hex(rgb) {
    if (typeof(rgb) == 'undefined') return 'FFFFFF';
    return msos.common.dec_to_hex(rgb[0]) + '' + msos.common.dec_to_hex(rgb[1]) + '' + msos.common.dec_to_hex(rgb[2]);
}